package javabase.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOServer {

	private static final int size = 4096;
	private ByteBuffer sendBuffer = ByteBuffer.allocate(size);
	private ByteBuffer receiveBuffer = ByteBuffer.allocate(size);
	
	private Selector selector;

	public NIOServer(int port) throws IOException {
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		serverSocketChannel.configureBlocking(false); //是否阻塞
		ServerSocket serverSocket = serverSocketChannel.socket();
		serverSocket.bind(new InetSocketAddress(port));
		// 打开选择器
		selector = Selector.open();
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		System.out.println("server listening on " + port);
	}
	
	//监听
	public void listen() throws IOException {
		while (true) {
			selector.select();
			Set<SelectionKey> keys = selector.selectedKeys();
			Iterator<SelectionKey> iterator = keys.iterator();
			while (iterator.hasNext()) {
				SelectionKey key = iterator.next();
				iterator.remove();
				handleKey(key);
			}
		}
	}
	
	public void handleKey(SelectionKey key) throws IOException {
		ServerSocketChannel serverSocketChannel = null;
		SocketChannel client = null;
		String receiveText;
		String sendText;
		int count = 0;
		if (key.isAcceptable()) {
			serverSocketChannel = (ServerSocketChannel) key.channel();
			client = serverSocketChannel.accept();
			client.configureBlocking(false);
			
			client.register(selector, SelectionKey.OP_READ);
		} else if (key.isReadable()) {
			client = (SocketChannel) key.channel();
			count = client.read(receiveBuffer);
			if (count > 0) {
				receiveText = new String(receiveBuffer.array(), 0, count);
				System.out.println("receive from client ：" + receiveText);
				client.register(selector, SelectionKey.OP_WRITE);
			}
		} else if (key.isWritable()) {
			sendBuffer.clear();
			client = (SocketChannel) key.channel();
			sendText = "dek";
			sendBuffer.put(sendText.getBytes());
			sendBuffer.flip();
			
			client.write(sendBuffer);
			System.out.println("send to client:" + sendText);
			client.register(selector, SelectionKey.OP_READ);
		}
		
	}
	
		
	public static void main(String[] args) throws IOException {
		NIOServer server = new NIOServer(8888);
		server.listen();
	}
}
